package com.zn.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import com.zn.vo.Response;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.CookieManager;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

/**
 * @author yinjiawei
 * @time 2018-08-08
 */
public class HttpClientUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientUtil.class);

//    private static String url="http://yb.zhqiquan.com/pay/Api/get_action";

    private static final OkHttpClient CLIENT = new OkHttpClient();
    private static final ObjectMapper MAPPER = new ObjectMapper();
    static {
        MAPPER.setTimeZone(TimeZone.getTimeZone("GMT+8"));
    }



    /**
     * GET 请求
     * @author yinjiawei
     * @time 3/15/18 12:23
     * @param builder
     */
    public static Response get(String url,Builder builder) {
        try {
            Request request = new Request.Builder()
                    .url(urlForGet(url, builder.getApi(), paramForGet(builder.get())))
                    .build();
            okhttp3.Response response = CLIENT.newCall(request).execute();
            String encoding = response.header("Content-Encoding");
            String json = response.body().string();
            LOGGER.info("encoding:......"+encoding+"....json:"+json);
            json=replaceSpecialtyStr(json,"","");
            return MAPPER.readValue(json, Response.class);
        } catch (Exception e ) {
            LOGGER.error("GET REQUEST ERROR", e);
            throw new RuntimeException(e);
        }
    }
    public static String get(Builder builder,String url) {
        try {
            Request request = new Request.Builder()
                    .url(urlForGet(url, builder.getApi(), paramForGet(builder.get())))
                    .build();
//            LOGGER.info("GET REQUEST URL "+url+builder.getApi());
            okhttp3.Response response = CLIENT.newCall(request).execute();
            String encoding = response.header("Content-Encoding");
            String json="";
            if(StringUtils.isNotBlank(encoding)){
                json=GZIPUtils.uncompressToString(response.body().bytes());
            }else{
                json = response.body().string();
            }
//            LOGGER.info("encoding:......"+encoding+"....json:"+json);
            json=replaceSpecialtyStr(json,"","");
            return json;
        } catch (Exception e ) {
            LOGGER.error("GET REQUEST ERROR", e);
            throw new RuntimeException(e);
        }
    }

    /**
     *
     * @param builder
     * @param url
     * @return
     */
    public static String proxyGet(Builder builder,String url) {
        try {
            OkHttpClient.Builder builder1 = new OkHttpClient.Builder();
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("192.168.10.1", 80));
            //设置连接超时时间
            builder1.connectTimeout(1, TimeUnit.MINUTES);
            builder1.proxy(proxy);
            OkHttpClient client = builder1.build();
            Request request = new Request.Builder()
                    .url(urlForGet(url, builder.getApi(), paramForGet(builder.get())))
                    .build();
            LOGGER.info("GET REQUEST URL "+url+builder.getApi());
            okhttp3.Response response = client.newCall(request).execute();
            String encoding = response.header("Content-Encoding");
            String json="";
            if(StringUtils.isNotBlank(encoding)){
                json=GZIPUtils.uncompressToString(response.body().bytes());
            }else{
                json = response.body().string();
            }
            LOGGER.info("encoding:......"+encoding+"....json:"+json);
            json=replaceSpecialtyStr(json,"","");
            return json;
        } catch (Exception e ) {
            LOGGER.error("GET REQUEST ERROR", e);
            throw new RuntimeException(e);
        }
    }

    public static Response proxyPost(String url,Builder builder) {
        try {
            RequestBody body = RequestBody.create(MediaType.parse("application/json"), paramForPost(builder.get()));
            LOGGER.info("REQUEST URL "+url+builder.getApi());
            Request request = new Request.Builder()
                    .url(urlForPost(url, builder.getApi()))
                    .post(body)
                    .build();
            OkHttpClient.Builder builder1 = new OkHttpClient.Builder();
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("106.14.140.7", 80));
            //设置连接超时时间
            builder1.connectTimeout(1, TimeUnit.MINUTES);
            builder1.proxy(proxy);
            OkHttpClient client = builder1.build();
            okhttp3.Response response = client.newCall(request).execute();
            String json = response.body().string();
            LOGGER.info(json);
            return MAPPER.readValue(json, Response.class);
        } catch (Exception e) {
            LOGGER.error("POST REQUEST ERROR", e);
            throw new RuntimeException(e);
        }
    }
    /**
     * POST请求
     * @author yinjiawei
     * @time 3/15/18 12:23
     * @param builder
     */
    public static Response post(String url,Builder builder) {
        try {
            RequestBody body = RequestBody.create(MediaType.parse("application/json"), paramForPost(builder.get()));
            LOGGER.info("REQUEST URL "+url+builder.getApi());
            Request request = new Request.Builder()
                    .url(urlForPost(url, builder.getApi()))
                    .post(body)
                    .build();
            okhttp3.Response response = CLIENT.newCall(request).execute();
            String json = response.body().string();
            LOGGER.info(json);
            return MAPPER.readValue(json, Response.class);
        } catch (Exception e) {
            LOGGER.error("POST REQUEST ERROR", e);
            throw new RuntimeException(e);
        }
    }

    public static String post(Builder builder,String url) {
        try {
            LOGGER.info("REQUEST URL "+url+builder.getApi());
            Map<String,Object> result=new HashMap<String,Object>();
            RequestBody body = RequestBody.create(MediaType.parse("application/json"), paramForPost(builder.get()));
            Request request = new Request.Builder()
                    .url(urlForPost(url, builder.getApi()))
                    .post(body)
                    .build();
            request.headers();
            okhttp3.Response response = CLIENT.newCall(request).execute();
            String cookie=response.header("Set-Cookie");
            if(StringUtils.isNotBlank(cookie)){
                result.put("cookie",cookie);
            }
            LOGGER.info("响应的 code:" + response.code() +"和message:"+response.message());
            LOGGER.info("以下是响应的header信息...............");
            Headers headers=response.headers();
            Set<String> headerName=headers.names();
            for(String name:headerName){
                String headerValue=response.header(name);
                LOGGER.info("name........."+name+",headerValue....."+headerValue);
            }
            String json = response.body().string();
            LOGGER.info("return......."+json);
            result.put("data", json);
            return json;
        } catch (Exception e) {
            LOGGER.error("POST REQUEST ERROR", e);
            throw new RuntimeException(e);
        }
    }
    /**
     * POST请求
     * @author yinjiawei
     * @time 3/15/18 12:23
     * @param builder
     */
    public static Response postFormData(String url,Builder builder) {
        try {
            RequestBody body = RequestBody.create(MediaType.parse("form-data"), paramForPost(builder.get()));
            Request request = new Request.Builder()
                    .url(urlForPost(url, builder.getApi()))
                    .post(body)
                    .build();
            okhttp3.Response response = CLIENT.newCall(request).execute();
            String json = response.body().string();
            LOGGER.info(json);
            return MAPPER.readValue(json, Response.class);
        } catch (Exception e) {
            LOGGER.error("POST REQUEST ERROR", e);
            throw new RuntimeException(e);
        }
    }

    /**
     * POST 请求URL拼接
     * @author yinjiawei
     * @time 3/15/18 12:25
     * @param url
     * @param api
     */
    public static String urlForPost(String url, String api) {
        return String.format("%s%s", url, api);
    }

    /**
     * GET 请求URL拼接
     * @author yinjiawei
     * @time 3/15/18 12:24
     * @param url 请求地址
     * @param api 请求接口
     * @param params 请求参数
     */
    public static String urlForGet(String url, String api, String params) {
        boolean nullParams;
        return String.format("%s%s%s%s", url, api, (nullParams = params == null) ? "" : "?",
                nullParams ? "" : params);
    }

    /**
     * 组装post参数
     * @author yinjiawei
     * @time 3/15/18 12:24
     * @param params
     */
    public static String paramForPost(Map<String, Object> params) throws JsonProcessingException {
        String jsonParams = MAPPER.writeValueAsString(params);
        LOGGER.info(jsonParams);
        return jsonParams;
    }

    /**
     * 组装Get参数
     * @author yinjiawei
     * @time 3/15/18 12:23
     * @param params
     */
    public static String paramForGet(Map<String, Object> params) {
        if (params.isEmpty()) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            sb.append(entry.getKey())
                    .append("=")
                    .append(entry.getValue())
                    .append("&");
        }
        return sb.substring(0, sb.length() - 1);
    }

    /**
     * Builder
     * @author yinjiawei
     * @time 3/15/18 12:23
     */
    public static class Builder {

        private Map<String, Object> map;
        private String api;

        private Builder(String api) {
            this.map = new LinkedHashMap<>();
            this.api = api;
        }

        public Builder with(String key, Object value) {
            map.put(key, value);
            return this;
        }

        public String getApi() {
            return this.api;
        }

        public static Builder builder(String api) {
            return new Builder(api);
        }

        public Map<String, Object> get() {
            return this.map;
        }
    }
    /**
     * //去除字符串中空格、换行、制表
     * @param str
     * @param pattern
     * @param replace
     * @return
     */
    public static String replaceSpecialtyStr(String str,String pattern,String replace){
        if(isBlankOrNull(pattern))
            pattern="\\s*|\t|\r|\n";
        if(isBlankOrNull(replace))
            replace="";
        return Pattern.compile(pattern).matcher(str).replaceAll(replace);
    }

    public static boolean isBlankOrNull(String str){
        if(null==str)return true;
        return str.length()==0;
    }

    public static void main(String[] args) {
//        HttpClientUtil httpClientUtil=new HttpClientUtil();
        Response response = HttpClientUtil.post("http://yb.zhqiquan.com",
                HttpClientUtil.Builder.builder("/pay/Api/get_action")
                        .with("mch_id", "18080217005966")
                        .with("pay_method", "1")
        );
        LOGGER.info("response:"+response);
    }
}
